package com.sqlcheck.controller;

import com.sqlcheck.common.response.ApiResponse;
import com.sqlcheck.dto.request.LLMOptimizeRequest;
import com.sqlcheck.dto.response.LLMConfigResponse;
import com.sqlcheck.dto.response.LLMOptimizationResult;
import com.sqlcheck.service.LLMOptimizationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;

@RestController
@RequestMapping("/llm-optimization")
@RequiredArgsConstructor
@Validated
@Slf4j
@Tag(name = "大模型优化", description = "大模型SQL优化相关接口")
public class LLMOptimizationController {

    private final LLMOptimizationService llmOptimizationService;

    @PostMapping("/optimize")
    @Operation(summary = "执行SQL优化", description = "使用大模型对SQL语句进行优化分析")
    @ApiResponses(value = {
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "优化成功", 
                content = @Content(schema = @Schema(implementation = LLMOptimizationResult.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误", 
                content = @Content(schema = @Schema(implementation = ApiResponse.class))),
            @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误", 
                content = @Content(schema = @Schema(implementation = ApiResponse.class)))
    })
    public ResponseEntity<ApiResponse<LLMOptimizationResult>> optimizeSql(
            @Valid @RequestBody @Parameter(description = "SQL优化请求") LLMOptimizeRequest request,
            @Parameter(description = "用户ID", required = true) @RequestParam Long userId,
            HttpServletRequest httpRequest) {
        
        log.info("收到SQL优化请求，用户ID: {}, 源数据库: {}, 目标数据库: {}", 
                userId, request.getSourceDbType(), request.getTargetDbType());
        
        try {
            String clientIp = getClientIpAddress(httpRequest);
            String userAgent = httpRequest.getHeader("User-Agent");
            
            LLMOptimizationResult result = llmOptimizationService.optimizeSql(
                request, userId, clientIp, userAgent
            );
            
            log.info("SQL优化完成，用户ID: {}", userId);
            return ResponseEntity.ok(ApiResponse.success(result));
            
        } catch (IllegalArgumentException e) {
            log.warn("SQL优化请求参数错误: {}", e.getMessage());
            return ResponseEntity.ok(ApiResponse.error(e.getMessage()));
            
        } catch (Exception e) {
            log.error("SQL优化处理失败", e);
            return ResponseEntity.ok(ApiResponse.error("SQL优化处理失败: " + e.getMessage()));
        }
    }

    @GetMapping("/config")
    @Operation(summary = "获取大模型配置", description = "获取当前用户可用的大模型配置信息")
    public ResponseEntity<ApiResponse<LLMConfigResponse>> getLLMConfig(
            @Parameter(description = "用户ID", required = true) @RequestParam Long userId) {
        
        log.debug("获取大模型配置，用户ID: {}", userId);
        
        try {
            LLMConfigResponse config = llmOptimizationService.getLLMConfig(userId);
            return ResponseEntity.ok(ApiResponse.success(config));
            
        } catch (Exception e) {
            log.error("获取大模型配置失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取大模型配置失败: " + e.getMessage()));
        }
    }

    @PostMapping("/test-connection")
    @Operation(summary = "测试大模型连接", description = "测试指定大模型配置的连接状态")
    public ResponseEntity<ApiResponse<Boolean>> testLLMConnection(
            @Valid @RequestBody @Parameter(description = "大模型配置") LLMOptimizeRequest.LLMConfig config) {
        
        log.info("测试大模型连接，提供商: {}, 模型: {}", config.getProvider(), config.getModelName());
        
        try {
            boolean connected = llmOptimizationService.testLLMConnection(config);
            log.info("大模型连接测试结果: {}", connected ? "成功" : "失败");
            return ResponseEntity.ok(ApiResponse.success(connected));
            
        } catch (Exception e) {
            log.error("测试大模型连接失败", e);
            return ResponseEntity.ok(ApiResponse.error("测试大模型连接失败: " + e.getMessage()));
        }
    }

    @GetMapping("/usage")
    @Operation(summary = "获取使用统计", description = "获取用户今日大模型使用统计")
    public ResponseEntity<ApiResponse<UsageStatistics>> getUsageStatistics(
            @Parameter(description = "用户ID", required = true) @RequestParam Long userId) {
        
        log.debug("获取用户使用统计，用户ID: {}", userId);
        
        try {
            int todayUsage = llmOptimizationService.getTodayUsage(userId);
            boolean canUse = llmOptimizationService.checkUsageLimit(userId);
            
            UsageStatistics stats = new UsageStatistics();
            stats.setTodayUsage(todayUsage);
            stats.setCanUse(canUse);
            
            return ResponseEntity.ok(ApiResponse.success(stats));
            
        } catch (Exception e) {
            log.error("获取用户使用统计失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取用户使用统计失败: " + e.getMessage()));
        }
    }

    @GetMapping("/health")
    @Operation(summary = "健康检查", description = "检查大模型服务健康状态")
    public ResponseEntity<ApiResponse<HealthStatus>> healthCheck() {
        log.debug("执行大模型服务健康检查");
        
        try {
            // 这里可以添加更详细的健康检查逻辑
            HealthStatus status = new HealthStatus();
            status.setStatus("UP");
            status.setMessage("大模型服务运行正常");
            
            return ResponseEntity.ok(ApiResponse.success(status));
            
        } catch (Exception e) {
            log.error("健康检查失败", e);
            
            HealthStatus status = new HealthStatus();
            status.setStatus("DOWN");
            status.setMessage("大模型服务异常: " + e.getMessage());
            
            return ResponseEntity.ok(ApiResponse.success(status));
        }
    }

    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }

    // 内部类用于返回使用统计
    public static class UsageStatistics {
        private int todayUsage;
        private boolean canUse;

        public int getTodayUsage() {
            return todayUsage;
        }

        public void setTodayUsage(int todayUsage) {
            this.todayUsage = todayUsage;
        }

        public boolean isCanUse() {
            return canUse;
        }

        public void setCanUse(boolean canUse) {
            this.canUse = canUse;
        }
    }

    // 内部类用于返回健康状态
    public static class HealthStatus {
        private String status;
        private String message;

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }
    }
}